-
Notifications
You must be signed in to change notification settings - Fork 551
Add PHPDoc documentation to Type, Scope, and Reflection interfaces #4866
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/Php/PhpVersion.php
Outdated
| * Represents a specific PHP version for version-dependent analysis behavior. | ||
| * | ||
| * The version is stored as PHP_VERSION_ID format (e.g. 80100 for PHP 8.1.0). | ||
| * Extension developers can access it via `Scope::getPhpVersion()` (which returns |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not mention Scope here, only constructor injection.
| * value is unused at runtime a warning is emitted, PHPStan will emit the | ||
| * warning during analysis and on older PHP versions too | ||
| * On PHP 8.5+ if the return value is unused at runtime, a warning is emitted. | ||
| * PHPStan reports this during analysis regardless of PHP version. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep the mention of NoDiscard attribute.
| * Describes one signature variant of a function or method. | ||
| * | ||
| * A function/method may have multiple ParametersAcceptor variants — for example, | ||
| * the built-in `array_map` function has different signatures depending on argument count. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use different example, like strtok or PDO::query().
|
|
||
| /** | ||
| * Returns false for typed properties (which always retain their declared type) | ||
| * and true for untyped properties (which take on the type of whatever is assigned). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not seem precise. Research this more. I think the main difference is properties with different read/write types like @Property but take me up on that claim.
| * | ||
| * When calling a method on a generic type, the method's parameter and return types | ||
| * need to be transformed by substituting template type parameters with their concrete | ||
| * arguments. This interface allows that resolution to be deferred and configured: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This exists mostly because of StaticType.
One main implementation is used by ObjectType, the other by StaticType. Research which is which and update the comments.
| * | ||
| * This is the return type of Type::getUnresolvedPropertyPrototype(), | ||
| * Type::getUnresolvedInstancePropertyPrototype(), and | ||
| * Type::getUnresolvedStaticPropertyPrototype(). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This exists mostly because of StaticType.
One main implementation is used by ObjectType, the other by StaticType. Research which is which and update the comments.
src/Type/Type.php
Outdated
| public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): ExtendedMethodReflection; | ||
|
|
||
| /** | ||
| * Unlike getMethod(), this defers template type resolution. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And static
| * Returns a new instance with all inner types mapped through $cb. Might | ||
| * return the same instance if inner types did not change. | ||
| * Returns a new instance with all inner types mapped through $cb. | ||
| * Returns the same instance if inner types did not change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not used directly but through TypeTraverser
|
|
||
| /** | ||
| * Traverses inner types while keeping the same context in another type. | ||
| * Like traverse(), but walks two types simultaneously. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not use directly but through SimultaneousTypeTraverser
| * | ||
| * $type->describe(VerbosityLevel::typeOnly()) // "string" | ||
| * $type->describe(VerbosityLevel::value()) // "'hello'" | ||
| * $type->describe(VerbosityLevel::precise()) // "non-empty-lowercase-string" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The precise level description is not the best and could be improvee. Research what types have different value vs precise description and update accordingly.
Document every method on the Type interface with descriptions of purpose, behavior, parameters, return values, and usage guidance. Key additions: - Interface-level doc explaining the central role of Type and the critical rule to never use instanceof for type checks - Core methods: isSuperTypeOf, accepts, equals, describe with examples - Class identification: getReferencedClasses vs getObjectClassNames vs getObjectClassReflections, getClassStringObjectType - Member access: canAccessProperties/canCallMethods/canAccessConstants and has*/get*/getUnresolved* patterns - Array operations: all 13 array transformation methods (chunk, flip, pop, shift, slice, splice, reverse, search, shuffle, etc.) - Offset access: isOffsetAccessible vs isOffsetAccessLegal, setOffsetValueType vs setExistingOffsetValueType - Type checking: all is* methods for scalars, strings, and arrays - Type conversion: all to* methods (toBoolean through toCoercedArgumentType) - Comparison: looseCompare, isSmallerThan, getSmallerType family - Templates: inferTemplateTypes, getReferencedTemplateTypes, traverse - Other: generalize, tryRemove, getFiniteTypes, hasTemplateOrLateResolvableType https://claude.ai/code/session_01Htkqstd1mz1dbevHT6Y437
Document every method on the Scope interface, ClassMemberAccessAnswerer interface, and NamespaceAnswerer interface with descriptions of purpose, behavior, parameters, return values, and usage guidance. Scope interface: - Interface-level doc explaining Scope as the analysis state at an AST position, listing all extension types that receive it as a parameter - File/context methods: getFile vs getFileDescription (trait handling), isDeclareStrictTypes, isInTrait/getTraitReflection - Function context: getFunction, getFunctionName, getParentScope - Variable tracking: hasVariableType, getVariableType, canAnyVariableExist (extract() handling), getDefinedVariables vs getMaybeDefinedVariables - Type resolution: getType (the core method), getNativeType (PHPDoc-free), getKeepVoidType (preserves void), getScopeType vs getType (deferred evaluation), getScopeNativeType - Name resolution: resolveName (self/static/parent handling), resolveTypeByName (preserves LSB via StaticType/ThisType) - Reflection helpers: getInstancePropertyReflection, getStaticPropertyReflection, getMethodReflection, getConstantReflection - Scope filtering: filterByTruthyValue/filterByFalseyValue for type narrowing in conditional branches - Context queries: isInClassExists, isInFunctionExists, isInClosureBind, isInAnonymousFunction, isInExpressionAssign, isUndefinedExpressionAllowed, isInFirstLevelStatement, getFunctionCallStack ClassMemberAccessAnswerer interface: - Interface-level doc explaining its role as visibility checker passed to Type methods for enforcing public/protected/private access - canReadProperty vs canWriteProperty (PHP 8.4 asymmetric visibility) - canCallMethod, canAccessConstant NamespaceAnswerer interface: - Interface-level doc explaining namespace resolution context https://claude.ai/code/session_01Htkqstd1mz1dbevHT6Y437
…pe and Scope interfaces Document all interfaces and classes reachable through parameter types and return types of the previously documented Type and Scope interfaces. This covers 31 files across the type system, reflection layer, and supporting infrastructure: - Core result types: TrinaryLogic, AcceptsResult, IsSuperTypeOfResult - Type system: VerbosityLevel, GeneralizePrecision, ConstantScalarType, TypeWithClassName - Reflection: ClassMemberReflection, PropertyReflection, ExtendedPropertyReflection, MethodReflection, ExtendedMethodReflection, FunctionReflection, ParameterReflection, ClassConstantReflection, ConstantReflection, ParametersAcceptor, ExtendedParametersAcceptor, PassedByReference, Assertions, AttributeReflection - Callables: CallableParametersAcceptor, SimpleThrowPoint, SimpleImpurePoint - Generics: TemplateTypeMap, TemplateTypeReference, TemplateTypeVariance - Prototype resolution: UnresolvedPropertyPrototypeReflection, UnresolvedMethodPrototypeReflection - PHP version: PhpVersion, PhpVersions https://claude.ai/code/session_01Htkqstd1mz1dbevHT6Y437
Based on git blame analysis of Type.php, document the recurring pattern of adding new methods to the Type interface as a bug fix strategy instead of scattering instanceof checks or utility calls across the codebase. https://claude.ai/code/session_01Htkqstd1mz1dbevHT6Y437
…ype interfaces CompoundType: Document the double-dispatch protocol for bidirectional type comparison, explaining why instanceof CompoundType is the correct pattern (unlike instanceof SomeSpecificType which is discouraged). Document all four methods with their decomposition semantics. AccessoryType: Document the marker interface's role as a refinement type that always lives inside an IntersectionType alongside a base type. Include a complete mapping table of all 13 implementations to their corresponding query methods on the Type interface. https://claude.ai/code/session_01Htkqstd1mz1dbevHT6Y437
…es, tags, or common knowledge https://claude.ai/code/session_01Htkqstd1mz1dbevHT6Y437
- PhpVersion: mention only constructor injection, not Scope - CallableParametersAcceptor: restore #[\NoDiscard] attribute mention - ParametersAcceptor: use strtok as multi-variant example - PropertyReflection: fix canChangeTypeAfterAssignment() description to explain it's about matching read/write types and property hooks - UnresolvedMethodPrototypeReflection: document ObjectType vs StaticType implementations (CalledOnType vs Callback) - UnresolvedPropertyPrototypeReflection: same as above - Type::getUnresolvedMethodPrototype(): add "and static type" to doc - Type::traverse(): note to use TypeTraverser::map() instead - Type::traverseSimultaneously(): note to use SimultaneousTypeTraverser - VerbosityLevel: improve precise level description with concrete examples Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5d9925c to
d272471
Compare
|
perfect AI use-case. awesome. |
Summary
Typeinterface: all 90+ methods documented with purpose, behavior, and usage guidanceScopeinterface and its parent interfaces (InternalScope,ClassMemberAccessAnswerer,NamespaceAnswerer)TypeandScope:ParametersAcceptor,PropertyReflection,MethodReflection,ClassConstantReflection,ExtendedMethodReflection,ExtendedPropertyReflection,FunctionReflection, etc.CompoundTypeandAccessoryTypeinterfaces explaining double-dispatch and intersection semanticsTrinaryLogic,AcceptsResult,IsSuperTypeOfResult,VerbosityLevel,GeneralizePrecision,TemplateTypeMap,TemplateTypeVariance, etc.Test plan
make teststo ensure nothing is broken🤖 Generated with Claude Code